package cn.jeeweb.modules.supervise.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.util.HtmlUtils;

import com.alibaba.druid.util.IOUtils;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.ff.common.util.log.FFLogFactory;

import cn.jeeweb.cache.MonitorTypeParaCache;
import cn.jeeweb.core.query.wrapper.EntityWrapper;
import cn.jeeweb.modules.monitor.entity.McMonitorOrg;
import cn.jeeweb.modules.monitor.service.IMcMonitorOrgService;
import cn.jeeweb.modules.monitor.service.IMcMonitorPatrolDetailService;
import cn.jeeweb.modules.monitor.service.IMcMonitorPatrolLogService;
import cn.jeeweb.modules.monitor.service.IMcProItemAlarmService;
import cn.jeeweb.modules.repo.service.IMcRepoStandardService;
import cn.jeeweb.modules.supervise.entity.McProItemImplementLog;
import cn.jeeweb.modules.supervise.entity.McProItemMonitorItem;
import cn.jeeweb.modules.supervise.entity.McProReport;
import cn.jeeweb.modules.supervise.entity.McProject;
import cn.jeeweb.modules.supervise.service.IExcelReportService;
import cn.jeeweb.modules.supervise.service.IMcProItemImplementLogService;
import cn.jeeweb.modules.supervise.service.IMcProItemMeasuringPointService;
import cn.jeeweb.modules.supervise.service.IMcProItemMonitorItemService;
import cn.jeeweb.modules.supervise.service.IMcProItemRealTimeMonDataService;
import cn.jeeweb.modules.supervise.service.IMcProItemStandardService;
import cn.jeeweb.modules.supervise.service.IMcProReportService;
import cn.jeeweb.modules.supervise.service.IMcProjectService;

 
public abstract class ExcelReportServiceAbastracImpl implements IExcelReportService
{
	protected Logger log = FFLogFactory.getLog(ExcelReportServiceAbastracImpl.class);

	protected McProReport report;
	
	protected CellStyle defualtStyle;
	protected McProject project;
	
	
	@Autowired
	protected IMcProReportService reportService;
	
	@Autowired
	protected IMcProjectService projectService;
	
	@Autowired
	protected IMcProItemMonitorItemService itemService;
	
	
	@Autowired
	protected IMcProItemStandardService itemStandardService;
	
	@Autowired
	protected IMcRepoStandardService standardService;
	
	@Autowired
	protected IMcProItemRealTimeMonDataService dataService;
	
	@Autowired
	protected IMcProItemAlarmService alarmService;
	
	@Autowired
	protected MonitorTypeParaCache monitorTypeParaCache;
	
	@Autowired
	protected IMcProItemMeasuringPointService pointService;
	
	
	
	@Autowired
	protected IMcProItemImplementLogService implementLogService;
	
	@Autowired
	protected IMcMonitorPatrolLogService mcMonitorPatrolLogService;
	
	@Autowired
	protected IMcMonitorPatrolDetailService mcMonitorPatrolDetailService;
	protected List<McProItemMonitorItem> itemList;
	
	@Autowired
	protected IMcMonitorOrgService orgService;
	
	protected McMonitorOrg org;
	protected Map<String,McProItemImplementLog> implLogMap = new HashMap<String,McProItemImplementLog>();
	
	public void buildImplLogMap(List<McProItemImplementLog> dataList)
	{
		for(McProItemImplementLog log : dataList)
		{
			String key = com.ff.common.util.format.DateUtil.DateToString(log.getCreateDate(),"yyy-MM-hh");
			implLogMap.put(key, log);
		}
	}
	
	public void createExcel()
	{
		FileOutputStream outStream = null;
		
		
		String path = this.getOutFile();
 		File outFile = new File(this.getBasePath() + path);
		if(!outFile.getParentFile().exists()){
			outFile.getParentFile().mkdirs();
        }
		
		 
		try
		{
			File templateFile = new File(this.getTemplate());
			FileInputStream bis=new FileInputStream(templateFile); 
	 
			Workbook workBook = new XSSFWorkbook(bis); ;

			this.createIndex(workBook);
			this.createTitlePage(workBook);
			this.createCatalog(workBook);
			this.createMain(workBook);
			this.createContent(workBook);
			
			outStream = new FileOutputStream(outFile);
			workBook.write(outStream);
			this.report.setRemarks("报告生成完毕");
			this.report.setReportPath(path);
		}
		catch(Exception e)
		{
			this.report.setRemarks("报告生成失败");
			log.error("error",e);
		} finally
		{
			try
			{
				if (null != outStream)
				{
					outStream.flush();
				}

			} catch (Exception e)
			{
				log.error(""+e);
			}
			try
			{
				if (null != outStream)
				{
					outStream.close();
				}

			} catch (Exception e)
			{
				log.error("close excel failed" + e);
			}
		}
		
		reportService.updateAllColumnById(this.report);

 	}
	public String getBasePath()
	{
		String classPath = this.getClass().getResource("/").getPath();
		classPath = classPath + "/../..";
		return classPath;
	}
	public void setData(McProReport report)
	{
		this.report = report; 
		project = this.projectService.selectById(report.getProjectId());
		Wrapper<McProItemMonitorItem> wrapper = new EntityWrapper<McProItemMonitorItem>(McProItemMonitorItem.class);
		wrapper.eq("projectId", project.getId());
 		itemList = itemService.selectList(wrapper );
 		org = this.orgService.selectById(project.getMonitorId());
 		
 		
 
	}
	
	@Override
	public String getTemplate() {
		// TODO Auto-generated method stub
		return "/template/template.xlsx";
	}
	protected void createCell(int start_x,int start_y,String content,Sheet sheet)
	{
		createCell(start_x,start_y,start_x,start_y,content,sheet,defualtStyle);
	}
	protected void createCell(int start_x,int start_y,int end_x,int end_y,String content,Sheet sheet)
	{
		createCell(start_x,start_y,end_x,end_y,content,sheet,defualtStyle);
	}
	
	protected void copy(int start,int end,int target,Sheet sheet,Workbook wb)
	{
		for(int i=0;i<=end-start;i++)
		{
			insertRow(target+i,sheet);
			 
			//copyRow(wb,sheet,start+i,target+i,false);
		}
		copyRows(start,end,target,sheet);
	}
	
	protected void insertRow(int row,Sheet sheet)
	{
		sheet.shiftRows(row, sheet.getLastRowNum()+1, 1,true,false);   
		 sheet.createRow(row);
	}
	
	public void copyRows(int startRow, int endRow, int pPosition,  
            Sheet sheet) {  
        int pStartRow = startRow;  
        int pEndRow = endRow;  
        int targetRowFrom;  
        int targetRowTo;  
        int columnCount;  
        CellRangeAddress region = null;  
        int i;  
        int j;  
        if (pStartRow == -1 || pEndRow == -1) {  
            return;  
        }  
        // 拷贝合并的单元格  
        for (i = 0; i < sheet.getNumMergedRegions(); i++) {  
            region = sheet.getMergedRegion(i);  
            if ((region.getFirstRow() >= pStartRow)  
                    && (region.getLastRow() <= pEndRow)) {  
                targetRowFrom = region.getFirstRow() - pStartRow + pPosition;  
                targetRowTo = region.getLastRow() - pStartRow + pPosition;  
                CellRangeAddress newRegion = region.copy();  
                newRegion.setFirstRow(targetRowFrom);  
                newRegion.setFirstColumn(region.getFirstColumn());  
                newRegion.setLastRow(targetRowTo);  
                newRegion.setLastColumn(region.getLastColumn());  
                sheet.addMergedRegion(newRegion);  
            }  
        }  
        // 设置列宽  
        for (i = pStartRow; i <= pEndRow; i++) {  
            Row sourceRow = sheet.getRow(i);  
            columnCount = sourceRow.getLastCellNum();  
            if (sourceRow != null) {  
                Row newRow = sheet.createRow(pPosition - pStartRow + i);  
                newRow.setHeight(sourceRow.getHeight());  
                for (j = 0; j < columnCount; j++) {  
                    Cell templateCell = sourceRow.getCell(j);  
                    if (templateCell != null) {  
                        Cell newCell = newRow.createCell(j);  
                        copyCell(templateCell, newCell);  
                    }  
                }  
            }  
        }  
    }  
  
  
     private void copyCell(Cell srcCell, Cell distCell) {  
        distCell.setCellStyle(srcCell.getCellStyle());  
        if (srcCell.getCellComment() != null) {  
            distCell.setCellComment(srcCell.getCellComment());  
        }  
        int srcCellType = srcCell.getCellType();  
        distCell.setCellType(srcCellType);  
        if (srcCellType == Cell.CELL_TYPE_NUMERIC) {  
            if (DateUtil.isCellDateFormatted(srcCell)) {  
                distCell.setCellValue(srcCell.getDateCellValue());  
            } else {  
                distCell.setCellValue(srcCell.getNumericCellValue());  
            }  
        } else if (srcCellType == Cell.CELL_TYPE_STRING) {  
            distCell.setCellValue(srcCell.getRichStringCellValue());  
        } else if (srcCellType == Cell.CELL_TYPE_BLANK) {  
            // nothing21  
        } else if (srcCellType == Cell.CELL_TYPE_BOOLEAN) {  
            distCell.setCellValue(srcCell.getBooleanCellValue());  
        } else if (srcCellType == Cell.CELL_TYPE_ERROR) {  
            distCell.setCellErrorValue(srcCell.getErrorCellValue());  
        } else if (srcCellType == Cell.CELL_TYPE_FORMULA) {  
            distCell.setCellFormula(srcCell.getCellFormula());  
        } else { // nothing29  
  
        }  
    }  
    public static void copyRow(Workbook wb,Sheet sheet, int fromRowInx, int toRowInx, boolean copyValueFlag) {
        
    	Row fromRow = sheet.getRow(fromRowInx);
    	Row toRow = sheet.getRow(toRowInx);
    			
    	toRow.setHeight(fromRow.getHeight());
        for(Iterator cellIt = fromRow.cellIterator(); cellIt.hasNext(); ) {
            Cell tmpCell = (Cell) cellIt.next();
            Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
            copyCell(wb, tmpCell, newCell, copyValueFlag);
        }
        Sheet worksheet = fromRow.getSheet();
        for(int i = 0; i < worksheet.getNumMergedRegions(); i++) {
            CellRangeAddress cellRangeAddress = worksheet.getMergedRegion(i);
            if(cellRangeAddress.getFirstRow() == fromRow.getRowNum()) {
                CellRangeAddress newCellRangeAddress = new CellRangeAddress(toRow.getRowNum(), (toRow.getRowNum() +
                        (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())), cellRangeAddress
                        .getFirstColumn(), cellRangeAddress.getLastColumn());
                worksheet.addMergedRegion(newCellRangeAddress);
            }
        }
    }

    /**
     * 复制单元格
     *
     * @param srcCell
     * @param distCell
     * @param copyValueFlag true则连同cell的内容一起复制
     */
    public static void copyCell(Workbook wb, Cell srcCell, Cell distCell, boolean copyValueFlag) {
        CellStyle newStyle = wb.createCellStyle();
        CellStyle srcStyle = srcCell.getCellStyle();
        newStyle.cloneStyleFrom(srcStyle);
        newStyle.setFont(wb.getFontAt(srcStyle.getFontIndex()));
        //样式
        distCell.setCellStyle(newStyle);
        //评论
        if(srcCell.getCellComment() != null) {
            distCell.setCellComment(srcCell.getCellComment());
        }
        // 不同数据类型处理
        int srcCellType = srcCell.getCellType();
        distCell.setCellType(srcCellType);
        if(copyValueFlag) {
            if(srcCellType == Cell.CELL_TYPE_NUMERIC) {
                if(DateUtil.isCellDateFormatted(srcCell)) {
                    distCell.setCellValue(srcCell.getDateCellValue());
                } else {
                    distCell.setCellValue(srcCell.getNumericCellValue());
                }
            } else if(srcCellType == Cell.CELL_TYPE_STRING) {
                distCell.setCellValue(srcCell.getRichStringCellValue());
            } else if(srcCellType == Cell.CELL_TYPE_BLANK) {

            } else if(srcCellType == Cell.CELL_TYPE_BOOLEAN) {
                distCell.setCellValue(srcCell.getBooleanCellValue());
            } else if(srcCellType == Cell.CELL_TYPE_ERROR) {
                distCell.setCellErrorValue(srcCell.getErrorCellValue());
            } else if(srcCellType == Cell.CELL_TYPE_FORMULA) {
                distCell.setCellFormula(srcCell.getCellFormula());
            } else {
            }
        }
    }
	protected void createCell(int start_x,int start_y,int end_x,int end_y,String content,Sheet sheet,CellStyle style)
	{
		Row row = sheet.getRow(start_x);
		if(null == row)
		{
			row = sheet.createRow(start_x);
		}
 		Cell cell = row.getCell(start_y);
 		if(null == cell)
		{
 			cell = row.createCell(start_y);
 			 
		}
 		if(null != content)
 		{
 			String temp = HtmlUtils.htmlUnescape(content);
 			cell.setCellValue(temp);
 		}
 		
 		CellRangeAddress region =new CellRangeAddress(start_x, end_x,start_y , end_y);
 		 sheet.addMergedRegion(region);
 		if(null != style)
		{
			cell.setCellStyle(style);
 	
	        RegionUtil.setBorderBottom(style.getBorderBottom(), region, sheet, sheet.getWorkbook());
	        RegionUtil.setBorderLeft(style.getBorderLeft(), region, sheet, sheet.getWorkbook());
	        RegionUtil.setBorderRight(style.getBorderRight(), region, sheet, sheet.getWorkbook());
	        RegionUtil.setBorderTop(style.getBorderTop(), region, sheet, sheet.getWorkbook());

		}
       
       
	}
	public CellStyle createDefaultStyle(Workbook workbook)
	{
		 CellStyle defualtStyle = workbook.createCellStyle(); // 单元格样式  
		 defualtStyle.setBorderBottom(CellStyle.BORDER_THIN);
		 defualtStyle.setBorderLeft(CellStyle.BORDER_THIN);
		 defualtStyle.setBorderRight(CellStyle.BORDER_THIN);
		 defualtStyle.setBorderTop(CellStyle.BORDER_THIN);

	     Font fontStyle = workbook.createFont(); // 字体样式  
	     fontStyle.setFontName("宋体"); // 字体 
	     fontStyle.setFontHeightInPoints((short) 9);
	     defualtStyle.setAlignment(CellStyle.ALIGN_CENTER);  
	     defualtStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
	     
	     defualtStyle.setFont(fontStyle);  
	     return defualtStyle;
	}
	public void createImage(int start_x,int start_y,int end_x,int end_y,String file,Sheet sheet)
	{
		createImage(start_x, start_y, end_x, end_y, file, sheet,1,1);
	}
	public void createImage(int start_x,int start_y,int end_x,int end_y,String file,Sheet sheet,double ratio_w,double ratio_h)
	{
		String fileName = this.getBasePath()+"/data/image/"+file;  

		if(file.startsWith(this.getBasePath()))
		{
			fileName = file;
		}
		  
		try
		{
			InputStream is = new FileInputStream(fileName);  
			byte[] bytes = IOUtils.readByteArray(is);  
			  
			int pictureIdx = sheet.getWorkbook().addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);  
			  
	        //CellRangeAddress titleRegion =new CellRangeAddress(start_x, end_x,start_y , end_y);
			//sheet.addMergedRegion(titleRegion);
			
			CreationHelper helper = sheet.getWorkbook().getCreationHelper();  
			Drawing drawing = sheet.createDrawingPatriarch();  
			//ClientAnchor anchor = drawing.createAnchor(0, 0, 1023, 255, start_x, start_x, end_y, end_x);
		   // CreationHelper helper = finalSheet.getWorkbook().getCreationHelper();
			ClientAnchor anchor = helper.createClientAnchor();
			  
			 //  anchor.setAnchorType(3);
			// 图片插入坐标  
			//double cellWidth = sheet.getColumnWidthInPixels(titleRegion.);
		   // double cellHeight = titleRegion.get
		   anchor.setCol1(start_y);  
			 anchor.setRow1(start_x);  
			 anchor.setCol2(end_y+1);
			 anchor.setRow2(end_x+1);
//			 anchor.setDx1(1000);
//			 anchor.setDy1(100);
//			  anchor.setDx2(-1000);
//			 anchor.setDy2(-100);
			 
			// anchor.setRow1(5);  
		     //   anchor.setCol1(3);  
		    //    anchor.setDx1(40);  
		    //    anchor.setDy1(8);  
		          
		   //     anchor.setRow2(5);  
		   //     anchor.setCol2(3);  
		    //    anchor.setDx2(741);  
		   //     anchor.setDy2(152); 
			// 插入图片  
			Picture pict = drawing.createPicture(anchor, pictureIdx);  
			//pict.r
		 
			  pict.resize(ratio_w,ratio_h);  
			 
		}
		catch(Exception e )
		{
			log.error("create image failed",e);
		}
	
	}
}
	
	 
